
package ca.kooki.codesnippet.views;

import java.text.ParseException;

import junit.framework.Assert;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Text;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import ca.kooki.codesnippet.Activator;
import ca.kooki.codesnippet.CodeSnippet;
import ca.kooki.codesnippet.Tag;
import ca.kooki.codesnippet.core.SystemDate;
import ca.kooki.codesnippet.core.User;

public class CodeSnippetSearchViewHandlerTest extends SwtTest {

  Tag tag;
  Text inputSearch;
  Composite outputResults;
  Button buttonSearch;
  CodeSnippetSearchViewHandler handle;
  
  @Before
  public void setUp() throws Exception {
    super.setUp();

    User aforward = new User("aforward");
    User james = new User("james");
    
    Activator.getDefault().getRepository().addUser(aforward);
    Activator.getDefault().getRepository().addUser(james);
    
    Activator.getDefault().getPreferences().setValue("user", "aforward");
    
    SystemDate.setNowTo("Dec 1, 1978 8:14 PM");
    tag = new Tag("t","k k2 k3 k4",new CodeSnippet("t1","kx ky kz","c1"),aforward);
    Tag anotherTag = new Tag("t2","l l2 l3 l4",new CodeSnippet("t3","lx ly lz","c2"),james);
    Tag anotherTagStill = new Tag("t4","m m2 m3 m4",new CodeSnippet("t5","2x 2y 2z","c3"),james);
    Activator.getDefault().getRepository().addTag(tag);
    Activator.getDefault().getRepository().addTag(anotherTag);
    Activator.getDefault().getRepository().addTag(anotherTagStill);
    
    
    ScrolledComposite scrolled = new ScrolledComposite(parent,SWT.NULL);
    outputResults = new Composite(scrolled,SWT.NULL);
    buttonSearch = new Button(parent,SWT.PUSH);
    inputSearch = new Text(parent,SWT.BORDER);
    
    handle = new CodeSnippetSearchViewHandler(inputSearch,outputResults,buttonSearch);
  }
  
  @After
  public void tearDown() throws Exception {
    super.tearDown();
    SystemDate.reset();
  }
  
  @Test
  public void createTagComposite() throws ParseException
  {
    Activator.getDefault().getPreferences().setValue("user", "james");
    
    Composite tagComposite = handle.createTagComposite(parent,tag);
    Assert.assertEquals(2,tagComposite.getChildren().length);
    
    Control[] allTagElements = tagComposite.getChildren();
    Assert.assertEquals(Link.class, allTagElements[0].getClass());
    Assert.assertEquals(Link.class, allTagElements[1].getClass());
    
    Link linkTitle = (Link)allTagElements[0];
    Link linkKeywords = (Link)allTagElements[1];
    
    Assert.assertEquals("t <a>show</a> <a>tag</a>",linkTitle.getText());
    Assert.assertEquals("to <a>k</a> <a>k2</a> <a>k3</a> <a>k4</a> on Dec 1, 1978 8:14 PM",linkKeywords.getText());
    Assert.assertEquals(tag,linkTitle.getData());
    Assert.assertEquals(tag.getUser(),linkKeywords.getData());
  }

  @Test
  public void editTheTag() throws ParseException
  {
    Activator.getDefault().getRepository().setUser("aforward");
    Composite tagComposite = handle.createTagComposite(parent,tag);
    Control[] allTagElements = tagComposite.getChildren();
    Link linkTitle = (Link)allTagElements[0];
    Assert.assertEquals("t <a>show</a> <a>edit</a>",linkTitle.getText());
  }

  
  @Test
  public void selectTheKeywordUpdateTheInput()
  {
    Composite tagComposite = handle.createTagComposite(parent,tag);
    Assert.assertEquals(2,tagComposite.getChildren().length);
    
    Control[] allTagElements = tagComposite.getChildren();
    Link link = (Link)allTagElements[1];
    
    Event e = new Event();
    e.widget = link;
    e.text = "k";
    e.data = tag.getUser();
    SelectionEvent event = new SelectionEvent(e);
    
    handle.widgetSelected(event);
    Assert.assertEquals("/aforward/k", inputSearch.getText());
    Assert.assertEquals(1, outputResults.getChildren().length);
  }

  @Test
  public void selectTheLinkExpandsTheCode()
  {
    Composite tagComposite = handle.createTagComposite(parent,tag);
    Assert.assertEquals(2,tagComposite.getChildren().length);
    
    Control[] allTagElements = tagComposite.getChildren();
    Link link = (Link)allTagElements[0];
    
    Event e = new Event();
    e.widget = link;
    e.text = "show";
    SelectionEvent event = new SelectionEvent(e);
    
    handle.widgetSelected(event);
    allTagElements = tagComposite.getChildren();
    Assert.assertEquals(3, allTagElements.length);
    Text outputCode = (Text)allTagElements[2];
    Assert.assertEquals("c1",outputCode.getText());

    handle.widgetSelected(event);
    allTagElements = tagComposite.getChildren();
    Assert.assertEquals(2, allTagElements.length);
  }
  
  @Test
  public void emptySearchShowsAllTagsForThatUser()
  {
    Event e = new Event();
    e.widget = buttonSearch;
    SelectionEvent event = new SelectionEvent(e);
    handle.widgetSelected(event);

    Composite tagComposite = (Composite)outputResults.getChildren()[0];
    Control[] allTagElements =  tagComposite.getChildren();
    Assert.assertEquals(Link.class, allTagElements[0].getClass());
    Assert.assertEquals(Link.class, allTagElements[1].getClass());
    
    Link linkTitle = (Link)allTagElements[0];
    Link linkKeywords = (Link)allTagElements[1];
    
    Assert.assertEquals("t <a>show</a> <a>edit</a>",linkTitle.getText());
    Assert.assertEquals("to <a>k</a> <a>k2</a> <a>k3</a> <a>k4</a> on Dec 1, 1978 8:14 PM",linkKeywords.getText());
    Assert.assertEquals(tag,linkTitle.getData());
    Assert.assertEquals(tag.getUser(),linkKeywords.getData());

    
  }
  
  @Test
  public void performPathSearch()
  {
    
    Event e = new Event();
    e.widget = buttonSearch;
    SelectionEvent event = new SelectionEvent(e);

    inputSearch.setText("/james/l/m");
    handle.widgetSelected(event);
    Assert.assertEquals(2, outputResults.getChildren().length);

    inputSearch.setText("/james/l");
    handle.widgetSelected(event);
    Assert.assertEquals(1, outputResults.getChildren().length);

  }
  
  
  @Test
  public void searchNoResults()
  {
    Activator.getDefault().getPreferences().setValue("user", "unknown");
    
    Event e = new Event();
    e.widget = buttonSearch;
    SelectionEvent event = new SelectionEvent(e);
    handle.widgetSelected(event);

    Label labelNoResults = (Label)outputResults.getChildren()[0];
    Assert.assertEquals("No results found, sorry!", labelNoResults.getText());
  }

  @Test
  public void clearResultsBeforeNewSearch()
  {

    Event e = new Event();
    e.widget = buttonSearch;
    SelectionEvent event = new SelectionEvent(e);
    
    handle.widgetSelected(event);
    Assert.assertEquals(1, outputResults.getChildren().length);

    handle.widgetSelected(event);
    Assert.assertEquals(1, outputResults.getChildren().length);

  }

  
  @Test
  public void showAllUserSnippets()
  {
    Event e = new Event();
    e.widget = buttonSearch;
    SelectionEvent event = new SelectionEvent(e);
    handle.widgetSelected(event);
    Assert.assertEquals(1,outputResults.getChildren().length);
  }

}
